#include <iostream>
#include <cstring>
#include "stdMystring.h"
StdMystring::StdMystring()
{
    // std::cout << "无参构造\n";
    this->size = 0;
    this->capacity = 15;
    this->s = new char[this->capacity];
    memset(this->s, 0, sizeof(s));
}
StdMystring::~StdMystring()
{
    // std::cout << "析构\n";
    this->size = 0;
    this->capacity = 0;
    delete[] this->s;
}
StdMystring StdMystring::number(int a)
{
    StdMystring s;
    sprintf(s.s, "%d", a);
    return s;
}
StdMystring::StdMystring(const char *str)
{
    // std::cout << "带参构造\n";
    this->size = strlen(str);
    if (strlen(str) <= 15)
    {

        this->capacity = 16;
        this->s = new char[this->capacity + 1];
        memset(this->s, 0, sizeof(s));
        strcpy(this->s, str);
    }
    else
    {
        this->capacity = this->size + 1;
        this->s = new char[this->capacity];
        memset(this->s, 0, this->capacity);
        strcpy(this->s, str);
    }
}
StdMystring::StdMystring(const StdMystring &str)
{
    // std::cout << "拷贝构造\n";
    this->capacity = str.capacity;
    this->size = str.size;
    this->s = new char[this->capacity];
    memset(this->s, 0, this->capacity);
    strcpy(this->s, str.s);
}
std::ostream &operator<<(std::ostream &os, const StdMystring &str)
{
    // os << "size=" << str.size << " "
    //    << "capacity=" << str.capacity << std::endl;
    os << str.s;
    return os;
}
std::istream &operator>>(std::istream &is, StdMystring &str)
{
#if 0
    /*行缓冲的最大大小1024字节*/
    char temp[1024] = {0};
    is >> temp;
    str = temp;
#endif
    char c = '\0';
    while (c = getchar() != '\n')
    {
        str += c;
    }
    return is;
}
std::ostream &operator<<(std::ostream &os, const MyStringList &list)
{
    for (int idx = 0; idx < list.size; idx++)
    {
        os << list.string[idx] << std::endl;
    }
    return os;
}
StdMystring StdMystring::operator+(const StdMystring &str)
{
    // StdMystring s1("hello");
    // StdMystring s2 (s1);
    StdMystring result(*this);
    result.size = this->size + str.size;
    if (result.size < result.capacity)
    {
        strcat(result.s, str.s);
    }
    else
    {
        result.capacity = result.size + 1;
        char *newStr = new char[result.capacity];
        strcpy(newStr, this->s);
        strcat(newStr, str.s);
        delete[] result.s;
        result.s = newStr;
    }
    return result;
}
/*赋值运算符深拷贝，否则二次释放
**要返回值的原因：连续赋值
**返回引用的原因：减少拷贝次数*/
StdMystring &StdMystring::operator=(const StdMystring &str)
{
    // std::cout << "赋值运算符重载\n";
    this->capacity = str.capacity;
    this->size = str.size;
    delete[] this->s;
    this->s = new char[str.capacity];
    strcpy(this->s, str.s);
    return *this;
}
StdMystring StdMystring::operator-(const StdMystring &str)
{
    StdMystring result(*this);
    char *deleteS = strstr(result.s, str.s);

    while (deleteS != nullptr)
    {
        char *backS = deleteS + str.size;
        while (*backS != '\0')
        {
            *deleteS++ = *backS++;
        }
        *deleteS = '\0';
        deleteS = strstr(result.s, str.s);
    }
    return result;
}
StdMystring &StdMystring ::operator+=(const StdMystring &str)
{
    *this = *this + str;
    return *this;
}
#if 0
StdMystring &StdMystring::operator+=(const char c)
{
    if (this->size + 1 == this->capacity)
    {
        this->capacity *= 2;
        char *newStr = new char[this->capacity];
        delete[] this->s;
        this->s = newStr;
    }
    this->s[this->size] = c;
    this->s[this->size + 1] = '\0';
    this->size++;
    return *this;
}
#endif
StdMystring &StdMystring::operator+=(const char c)
{
    if (this->size + 1 == this->capacity)
    {
        this->capacity *= 2;
        char *newStr = new char[this->capacity];
        strcpy(newStr, this->s);
        delete[] this->s;
        this->s = newStr;
    }
    this->s[this->size] = c;
    this->s[this->size + 1] = '\0';
    this->size++;
    return *this;
}
MyStringList StdMystring::split(const StdMystring &str)
{
    StdMystring temp(*this);
    MyStringList list;
    char *s = strtok(temp.s, str.s);
    while (s != nullptr)
    {
        list += s;
        s = strtok(nullptr, str.s);
    }
    return list;
}

bool StdMystring::operator==(const StdMystring &str)
{
    return strcmp(this->s, str.s) == 0;
}
bool StdMystring::operator!=(const StdMystring &str)
{
    return strcmp(this->s, str.s) != 0;
}
bool StdMystring::operator>(const StdMystring &str)
{
    return strcmp(this->s, str.s) > 0;
}

bool StdMystring::operator&&(const StdMystring &str)
{
    return this->size != 0 && str.size != 0;
}

char &StdMystring::operator[](int index)
{
    return this->s[index];
}

StdMystring::operator int()
{
    return atoi(this->s);
}

StdMystring::operator double()
{
    return atof(this->s);
}

MyStringList::MyStringList()
{
    this->size = 0;
    this->capacity = 15;
    this->string = new StdMystring[this->capacity];
}

MyStringList::~MyStringList()
{
    delete[] this->string;
}

void MyStringList::removeByIndex(int index)
{
    if (index < 0 || index >= this->size)
    {
        return;
    }
    for (int idx = index; idx < this->size - 1; idx++)
    {
        this->string[idx] = this->string[idx + 1];
    }
    this->size--;
}

MyStringList &MyStringList::operator+=(const StdMystring &str)
{
    if (this->size == this->capacity)
    {
        this->capacity *= 2;
        StdMystring *newPtr = new StdMystring[this->capacity];
        for (int idx = 0; idx < this->size; idx++)
        {
            newPtr[idx] = this->string[idx];
        }
        delete[] this->string;
        this->string = newPtr;
    }
    this->string[this->size++] = str;
    return *this;
}

MyStringList &MyStringList::operator-=(const StdMystring &str)
{
    for (int idx = 0; idx < this->size; idx++)
    {
        if (this->string[idx] == str)
        {
            removeByIndex(idx);
            idx--;
        }
    }
    return *this;
}

StdMystring &MyStringList::operator[](int idx)
{
    return this->string[idx];
}
